********************************************************************************
********************************************************************************
********************************************************************************
* DENTLER, BLINZLER AND QUINLAN - ELECTORAL MESSIAH OR PARTY LABEL?
* Devised by KB
* Last updated: Wednesday, October 18, 2023
* Apply syntax to 1998-2021 Timeseries Dataset ("1998_2021_timeseries.dta")
* File Created under Stata Version 16.1, Platform: MacOSX
********************************************************************************
********************************************************************************
********************************************************************************

********************************************************************************
********************************************************************************
**>>> SYNTAX FILE TABLE OF CONTENTS
** 1: INSTRUCTIONS FOR USE OF SYNTAX FILE, PURPOSE OF SYNTAX FILE AND STATA SETUP
** 2: VOTER TYPOLOGY VARIABLE FOLLOWING QUINLAN & MCALLISTER
** 3: VOTE CHOICE VARIABLE 
** 4: FIGURE 1 - PARTY-LEADER POPULARITY INDEX (MID CATEGORY = 4-6)
** 5: FIGURE 2 - QUINLAN & MCALLISTER DESCRIPTIVE INDEX
** 6: FIGURE 3 - DESCRIPTIVE INDEX BY PARTY VOTE (2021)
** 7: FIGURE 4 - MULTINOMIAL MODEL FOR 2021 ELECTION
********************************************************************************
********************************************************************************

********************************************************************************
********************************************************************************
**#>>> 1: INSTRUCTIONS FOR USE OF SYNTAX FILE, PURPOSE OF SYNTAX FILE
**        AND STATA SETUP
********************************************************************************
********************************************************************************

********************************************************************************
**// INSTRUCTIONS FOR NAVIGATING FILE
********************************************************************************

** #>>> = Section Heading
** //  = Subsection Heading
** <<< = Heading for Code Instruction / Explanation


********************************************************************************
**// PURPOSE INSTRUCTIONS FOR NAVIGATING FILE
********************************************************************************
* This do-file serves to convey all modifications and analyses applied to the 
* 1998-2021 Timeseries Dataset, as reported in the Dentler, Blinzler and 
* Quinlan paper "ELECTORAL MESSIAH OR PARTY LABEL? QUANTIFYING AND INVESTIGATING
* LEADER-PARTY RELATIONSHIPS IN GERMAN FEDERAL ELECTIONS 1998–2021". 



********************************************************************************
**// SETUP STATA 
********************************************************************************

*<<< specify version of Stata used for this session
version 16.1 

*<<< clears the stata session and close all open files, windows & dialoge boxes:
clear all

*<<< mute pause or display --more-- messages in results window:
set more off 

*<<< set maximum scrollback-option for Stata results window:
set scrollbufsize 2000000 


********************************************************************************
**// INSTALL ADD-ONS FOR STATA
********************************************************************************

*<<< Install estout to enable transfers of tables from STATA to Word
ssc install estout, replace
ssc describe estout

*<<< Install fre to enable formatted frequency tables in Stata results window
ssc install fre, replace 
ssc describe fre

*<<< Install fitstat to enable additional goodness of fit measures
ssc install fitstat, replace
ssc describe fitstat



********************************************************************************
**//  LOADING DATA INTO STATA
********************************************************************************

*<<< Loading Dataset:
use "./Processed Data/1998_2021_timeseries.dta", clear

*<<< Drop German 2002 studies as leader measures are unavailable for them: 
drop if study_year == 2002


********************************************************************************
********************************************************************************
**#>>> 2: VOTER TYPOLOGY VARIABLE FOLLOWING QUINLAN & MCALLISTER
********************************************************************************
********************************************************************************

*<<< Required variable: 1. Leader inclined, 2. Leader leaning, 3. Party and Leader,
*                       4. Party leaning, 5. Party inclined, 6. Incongruent 

*<<< Recode the existing variable accordingly to reorder groups:
gen typesofvoter_2 = .
replace typesofvoter_2 = 1 if typesofvoter == 1 // Leader inclined voter
replace typesofvoter_2 = 2 if typesofvoter == 5 // Leader leaning voter
replace typesofvoter_2 = 3 if typesofvoter == 3 // Party and leader inclined voter
replace typesofvoter_2 = 4 if typesofvoter == 6 // Party leaning voter
replace typesofvoter_2 = 5 if typesofvoter == 2 // Party inclined voter
replace typesofvoter_2 = 6 if typesofvoter == 4 // Incongruent voter 

tab typesofvoter_2 typesofvoter, m 

*<<< drop the old version of the voter type variable:
drop typesofvoter 

*<<< rename the updated typesofvoter variable:
rename typesofvoter_2 typesofvoter 

*<<< Assign variable and value labels: 
lab var typesofvoter "Types of Voters"
lab def types_lab_2 1 "Leader inclined voter" ///
                  2 "Leader leaning voter" ///
				  3 "Party & leader inclined voter" ///
				  4 "Party leaning voter" ///
				  5 "Party inclined voter" ///
				  6 "Incongruent voter"
lab val typesofvoter types_lab_2 

*<<< add numeric party codes to value labels:
numlabel types_lab_2, add

tab typesofvoter, m


********************************************************************************
********************************************************************************
**#>>> 3: VOTE CHOICE VARIABLE
********************************************************************************
********************************************************************************

*<<< identify multinomial vote choice variable:
tab vote_pl 
fre vote_pl

*<<< generate a new variable where we could drop "Other Party":
gen vote_all = vote_pl

*<<< drop "Other Party" from new vote choice variable:
replace vote_all = .a if vote_all == 801 
tab vote_all, m


********************************************************************************
********************************************************************************
**#>>> 4: FIGURE 1 - PARTY-LEADER POPULARITY INDEX (MID CATEGORY = 4-6):
********************************************************************************
********************************************************************************

********************************************************************************
**//  CREATING TRICHOTOMIES (DISLIKE, NEUTRAL, LIKE) FOR ALL PARTIES:
********************************************************************************

*<<< specify loop applied to the following parties:
foreach party in cdu spd green fdp left afd {

*<<< generate original trichotomy for each party:
recode PartyLike_`party' (0/3 = 0) (4/6 = 1) (7/10 = 2) (-1  = .), gen(trichotomy_orig_`party')

*<<< label original trichotomy variable:
lab var trichotomy_orig_`party' "Party Likeability: `party' (trichotomy)"
lab def trichotomy_`party' 0 "Does not like: `party'" ///
                                  1 "Neutral: `party'" ///
								  2 "Likes: `party'" ///
								  99 "Missing", modify 
lab val trichotomy_orig_`party' trichotomy_`party'
numlabel trichotomy_`party', add 

*<<< check coding of original trichotomy for each party:
tab PartyLike_`party' trichotomy_orig_`party', m

table () (study_year) [aw=sample_weight] if study_year != 2002, stat(fvpercent trichotomy_orig_`party') missing

}

********************************************************************************
**//  CREATING TRICHOTOMIES (DISLIKE, NEUTRAL, LIKE) FOR ALL LEADERS:
********************************************************************************

*<<< specify loop applied to the following party leaders:
foreach party in cdu spd green fdp left afd {

*<<< generate original trichotomy for all party leader likability variables:
recode LeaderLike_`party' (0/3 = 0) (4/6 = 1) (7/10 = 2) (-1 . = 99), gen(trichotomy_orig_`party'Leader)

*<<< label all original trichotomies:
lab var trichotomy_orig_`party'Leader "Leader Likeability: `party' (trichotomy)"
lab def trichotomy_`party'Leader 0 "Does not like: `party' leader" ///
                                  1 "Neutral: `party' leader" ///
								  2 "Likes: `party' leader" ///
								  99 "Missing", modify 
lab val trichotomy_orig_`party'Leader trichotomy_`party'Leader
numlabel trichotomy_`party'Leader, add 

*<<< check coding of all original trichotomies:
tab LeaderLike_`party' trichotomy_orig_`party'Leader, m

table () (study_year) [aw=sample_weight] if study_year != 2002, stat(fvpercent trichotomy_orig_`party'Leader) missing

}

***
* NOTE: Graph created in Excel based on the above output.
***


********************************************************************************
**//  VERIFICATION OF ALL NUMBERS PROVIDED IN FIGURE 1 WITH STATA:
********************************************************************************

*<<< specify loop applied to the following parties:
foreach party in cdu spd green fdp left afd {
	*<<< for each party, create dummy for respondents disliking party: 
	gen dislikes`party' = 1 if trichotomy_orig_`party' == 0 
	replace dislikes`party' = 0 if inlist(trichotomy_orig_`party', 1, 2)
	
	*<<< for each party, create dummy for respondents disliking leader: 
	gen dislikesleader`party' = 1 if trichotomy_orig_`party'Leader == 0
	replace dislikesleader`party' = 0 if inlist(trichotomy_orig_`party'Leader, 1, 2)
}

*<<< creating a new frame "tricho_orig_totals" that includes the same data as 
*    the default frame: 
frame copy default tricho_orig_totals

* NOTE: For two useful introductions to "frames" in Stata see:
*       https://www.stata.com/features/overview/multiple-datasets-in-memory/
*       https://blog.stata.com/2019/09/06/fun-with-frames/

*<<< switch to "tricho_orig_totals" frame:
frame change tricho_orig_totals

*<<< collapsing all party and leader dislike dummies with their mean 
* (i.e., % of respondents disliking party/leader) by election year:
collapse (mean) dislikes* [aw=sample_weight], by(study_year)

* Result: - One variable for each party including % of respondents disliking the 
*           party (like-dislike scale = 0-3) by election yesr
*         - One variable for each leader including % of respondents disliking the 
*           leader (like-dislike scale = 0-3) by election year 
*       --> six parties + six leaders = 12 variables with aggregate numbers in total  


*<<< specify loop applied to the following parties:
foreach party in cdu spd green fdp left afd {
	*<<< for each party, create a "diff_*" variable subtracting % of 
	*     leader-dislikers from  party dislikers:
	gen diff_`party' = round(((dislikes`party' - dislikesleader`party')*100), .01)
	display ""
	display"`party'"
	*<<< for each party, display results by election year for verification of Figure 1:
	table () (study_year), stat(mean diff_`party') missing
}

*<<< change the frame back to default, with the whole dataset loaded 
frame change default 

*<<< drop the frame used for verification of Figure 1:
frame drop tricho_orig_totals


********************************************************************************
********************************************************************************
**#>>> 5: FIGURE 2 - QUINLAN & MCALLISTER DESCRIPTIVE INDEX
********************************************************************************
********************************************************************************

tab typesofvoter, m

*<<< display numbers used to generate Figure 2:
bysort study_year: tab typesofvoter [aw = sample_weight]

***
* NOTE: Graph created in Excel based on the above output.
***

********************************************************************************
********************************************************************************
**#>>> 6: FIGURE 3 - DESCRIPTIVE INDEX BY PARTY VOTE (2021)
********************************************************************************
********************************************************************************

*<<< display numbers used to generate Figure 3:
bysort typesofvoter: tab vote_pl [aw = sample_weight] if study_year == 2021

***
* NOTE: Graph created in Excel based on the above numeric output.
***


********************************************************************************
********************************************************************************
**#>>> 7: FIGURE 4 - MULTINOMIAL MODEL FOR 2021 ELECTION
********************************************************************************
********************************************************************************


*<<< numbers for grey histogram in Figure 4: 
tab typesofvoter if study_year == 2021

*<<< multinomial logit as reported in Table E1.1: 
mlogit vote_all ib5.typesofvoter female age university church_attendance east lr_self if study_year == 2021 [pweight=sample_weight], baseoutcome(1) // Union as reference 

*<<< display additional goodness of fit measures:
fitstat
estat ic 

*<<< calculating marginal effects:
margins, at(typesofvoter=(1(1)6)) 

***
* NOTE: Graph created in Excel based on the above numeric output from margins.
* First digit in margins output devises party as coded in variable vote_all
* Second digit in margins output devises voter type as coded in variable typesofvoter
***


********************************************************************************
********************************************************************************

*<<< drop all stored estimates from memory: 
clear all

********************************************************************************
********************************************************************************

* END OF FILE
